package com.party.admin.biz.system;

import com.google.common.collect.Lists;
import com.party.core.utils.MyBeanUtils;
import com.party.admin.utils.RealmUtils;
import com.party.common.constant.Constant;
import com.party.common.utils.PasswordUtils;
import com.party.common.utils.PinyinUtil;
import com.party.common.utils.StringUtils;
import com.party.common.utils.img.CompressInput;
import com.party.core.model.YesNoStatus;
import com.party.core.model.charge.PackageMember;
import com.party.core.model.distributor.DistributorRelation;
import com.party.core.model.member.Expert;
import com.party.core.model.member.Member;
import com.party.core.model.member.PackageCount;
import com.party.core.model.system.*;
import com.party.core.service.charge.IPackageMemberService;
import com.party.core.service.cos.CosBizService;
import com.party.core.service.distributor.IDistributorRelationService;
import com.party.core.service.member.IExpertService;
import com.party.core.service.member.IMemberService;
import com.party.core.service.member.IPackageCountService;
import com.party.core.service.notify.IInstanceService;
import com.party.core.service.system.IMemberSysRoleService;
import com.party.core.service.system.ISysConfigService;
import com.party.core.service.system.ISysRoleService;
import com.party.notify.notifyPush.servce.INotifySendService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Service
public class MemberBizService {

    @Autowired
    private IMemberService memberService;

    @Autowired
    private IExpertService expertService;

    @Autowired
    private ISysRoleService sysRoleService;

    @Autowired
    private IMemberSysRoleService memberSysRoleService;

    @Autowired
    private INotifySendService notifySendService;

    @Autowired
    private CosBizService cosBizService;

    @Autowired
    private IPackageCountService packageCountService;

    @Autowired
    private ISysConfigService sysConfigService;

    @Autowired
    private IInstanceService instanceService;

    @Autowired
    private IPackageMemberService packageMemberService;

    @Autowired
    private IDistributorRelationService distributorRelationService;

    protected static Logger logger = LoggerFactory.getLogger(MemberBizService.class);


    /**
     * 保存业务数据
     *
     * @param member 会员信息
     * @return 会员信息
     * @throws Exception 异常信息
     */
    public Member saveBiz(Member member, Integer type) throws Exception {
        if (StringUtils.isEmpty(member.getId())) {

            // 新增
            String realname = member.getRealname();
            if (StringUtils.isNotBlank(realname)) {
                realname = PinyinUtil.filterEmoji(realname, "");
                member.setRealname(realname);
                member.setPinyin(PinyinUtil.hanziToPinyin(realname, ""));
            }
            member.setPassword(PasswordUtils.encryptPassword(Constant.DEFALT_PASSWORD));
            if (member.getIsAdmin() == null) {
                member.setIsAdmin(YesNoStatus.NO.getCode());
            }
            if (member.getIsExpert() == null) {
                member.setIsExpert(YesNoStatus.NO.getCode());
            }
            if (member.getIsDistributor() == null) {
                member.setIsDistributor(YesNoStatus.NO.getCode());
            }
            if (member.getIsPartner() == null) {
                member.setIsPartner(YesNoStatus.NO.getCode());
            }
            if (member.getIsCopartner() == null) {
                member.setIsCopartner(YesNoStatus.NO_NEW.getCode());
            }
            if (member.getIsCosponsor() == null) {
                member.setIsCosponsor(YesNoStatus.NO.getCode());
            }
            member.setPicNum(0);
            member.setType(type);

            String memberId = memberService.insert(member);// 保存

            List<SysRole> sysRoles = Lists.newArrayList();
            String systemRole = "";
            if (member.getIsDistributor() != null && member.getIsDistributor() == 1) {
                systemRole = RoleEnum.DISTRIBUTOR_ROLE.getCode();
            }
            if (member.getIsPartner() != null && member.getIsPartner() == 1) {
                systemRole = RoleEnum.PARTNER_ROLE.getCode();

                // 合作商经典版
                String businessRole = RoleEnum.PARTNER_2_ROLE.getCode();
                SysRole sysRole = getSysRole(businessRole, RoleType.PARTNER_ROLE.getCode());
                sysRoles.add(sysRole);
            }
            if (member.getIsCopartner() != null && member.getIsCopartner() == 1) {
                systemRole = RoleEnum.COPARTNER_ROLE.getCode();
            }

            // 分配系统角色
            if (StringUtils.isNotEmpty(systemRole)) {
                SysRole sysRole = getSysRole(systemRole, RoleType.SYSTEM_ROLE.getCode());
                sysRoles.add(sysRole);
            }
            for (SysRole sysRole : sysRoles) {
                MemberSysRole memberSysRole = new MemberSysRole(memberId, sysRole.getId());
                memberSysRoleService.insert(memberSysRole);
            }
            return member;
        } else {

            // 从数据库取出记录的值
            Member t = memberService.get(member.getId());

            // 将编辑表单中的非NULL值覆盖数据库记录中的值
            MyBeanUtils.copyBeanNotNull2Bean(member, t);

            String realname = t.getRealname();
            if (StringUtils.isNoneBlank(realname)) {
                realname = PinyinUtil.filterEmoji(realname, "");
                t.setRealname(realname);
                t.setPinyin(PinyinUtil.hanziToPinyin(realname, ""));
            }
            memberService.update(t);
            return t;
        }
    }

    /**
     * 获取系统角色
     *
     * @param code 角色代码
     * @param type 类型
     * @return 系统角色
     */
    public SysRole getSysRole(String code, Integer type) {
        SysRole t = new SysRole();
        t.setCode(code);
        t.setType(type);
        return sysRoleService.uniqueProperty(t);
    }

    /**
     * 保存达人
     *
     * @param entity 会员信息
     */
    public void saveExpert(Member entity) {
        Expert ex = expertService.findByMemberId(entity.getId());
        Integer isExpert = entity.getIsExpert();
        if (ex == null && isExpert != null && isExpert == 1) {
            ex = new Expert();
            ex.setMemberId(entity.getId());
            expertService.insert(ex);
            notifySendService.sendExpertApprove(entity.getId());
        } else if (ex != null && isExpert != null && isExpert == 0) {
            expertService.delete(ex.getId());
            notifySendService.sendExpertCancel(entity.getId());
        }
    }

    /**
     * 若用户头像不是万象优图的路径，则上传修改为万象优图图片， 用于做定时任务更新
     *
     * @param limit 每个循环更新的数量，防止内存溢出
     */
    public void updateMemberLogoToCloud(Integer limit) {
        String[] errorPaths = {
                "/var/mobile", "/storage/"
        };


        Integer start = 0;
        while (true) {
            List<Member> remoteLogoList = memberService.getRemoteLogoList(start, limit);
            if (remoteLogoList.size() == 0) {
                break;
            }
            for (Member member : remoteLogoList) {
                if ("".equals(member.getLogo()) || "undefined".equals(member.getLogo()) || "/0".equals(member.getLogo())) {
                    continue;
                }

                try {
                    boolean isError = false;

                    for (String errorPath : errorPaths) {
                        if (member.getLogo().indexOf(errorPath) != -1) {
                            isError = true;
                            break;
                        }
                    }
                    if (isError) {
                        continue;
                    }

                    CompressInput compressInput = new CompressInput();
                    try {
                        int imageLength = cosBizService.getImageLength(member.getLogo());
                        if (imageLength > 1024 * 100) {
                            // 图片压缩参数
                            compressInput.setMaxWidth(440);
                            compressInput.setStrUrl(member.getLogo());
                        } else {
                            compressInput = null;
                        }
                    } catch (Exception e) {
                        logger.error("获取图片大小异常", e);
                    }
                    Map uploadRet = cosBizService.uploadImgRemote(member.getLogo().replace("https:", "http:"), member.getId(), "", compressInput);
                    if (uploadRet != null) {
                        Map<String, Object> urlRet = cosBizService.handelImgUrl((Map) uploadRet.get("data"));
                        logger.info("万象优图更新用户{}头像{}为{}", member.getId(), member.getLogo(), urlRet.get("cdnUrl"));
                        member.setLogo((String) urlRet.get("cdnUrl"));
                        memberService.update(member);
                    }
                } catch (Exception e) {
                    logger.error("updateMemberLogoToCloud 异常", e);
                    continue;
                }
            }
            start += limit;
        }
    }

    /**
     * 用户套餐使用控制保存
     *
     * @param pc
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void savePackageCountBiz(PackageCount pc) throws Exception {
        String currentId = RealmUtils.getCurrentUser().getId();
        String memberId = pc.getMemberId();
        String type = pc.getType();
        Integer quantity = pc.getQuantity();
        if (StringUtils.isNotEmpty(memberId) && StringUtils.isNotEmpty(type)) {
            PackageCount packageCount = packageCountService.getUnique(new PackageCount(memberId, type));
            if (packageCount == null) {
                // 短信预警默认配置
                SysConfig smsWarnConfig = sysConfigService.findByCode(PackageCount.SMS_WARN_NUM_DEFAULT);
                // 短信超出使用默认配置
                SysConfig smsExcessConfig = sysConfigService.findByCode(PackageCount.SMS_EXCESS_NUM_DEFAULT);

                packageCount = pc;
                if (null == packageCount.getIsOpen()) {
                    packageCount.setIsOpen(YesNoStatus.NO_NEW.getCode()); // 默认关闭
                }
                if (smsWarnConfig != null) {
                    packageCount.setWarnNum(Integer.valueOf(smsWarnConfig.getValue()));
                } else {
                    packageCount.setWarnNum(0);
                }
                if (smsExcessConfig != null) {
                    packageCount.setExcessNum(Integer.valueOf(smsExcessConfig.getValue()));
                } else {
                    packageCount.setExcessNum(0);
                }
                packageCount.setTotalNum(0);
                packageCount.setUseNum(0);
            }
            if (quantity != null) {
                packageCount.setTotalNum(packageCount.getTotalNum() + quantity);
                Integer useNum = instanceService.getSmsSendSuccess(memberId);
                packageCount.setUseNum(useNum);

                Integer tempTotalNum = packageCount.getTotalNum() - packageCount.getUseNum();
                packageCount.setTempTotalNum(tempTotalNum);
            }

            if (packageCount.getTotalNum() - packageCount.getUseNum() > 0) {
                packageCount.setIsWarned(YesNoStatus.NO_NEW.getCode());
            }

            packageCount.setUpdateBy(currentId);
            if (StringUtils.isEmpty(packageCount.getId())) {
                packageCountService.insert(packageCount);
            } else {
                if (quantity == null) {
                    packageCount.setExcessNum(pc.getExcessNum());
                    packageCount.setWarnNum(pc.getWarnNum());
                    packageCount.setIsOpen(pc.getIsOpen());
                    packageCount.setIsAllowExcess(pc.getIsAllowExcess());
                }
                packageCountService.update(packageCount);
            }
            if (pc.getType().equals(TargetType.PUSH_SMS.getCode()) && null != quantity) {
                //更新package_member数据
                PackageMember packageMember = new PackageMember();
                packageMember.setMemberId(memberId);
                packageMember.setQuantity(quantity);
                packageMember.setStatus(1);
                packageMember.setPayStatus(2);
                packageMember.setSmsSource(3);
                packageMember.setPrice(0f);
                packageMemberService.insert(packageMember);
            }
        }
    }

    /**
     * 初始化联合发起人
     * 增加CEO户外联盟成员角色 member的type标记为1（个人）、is_copartner标记为1
     */
    public void initRepresentData() {
        DistributorRelation relation = new DistributorRelation();
        relation.setType(4);
        List<String> memberIds = distributorRelationService.getDistributors(relation);
        for (String memberId : memberIds) {
            Member member = memberService.get(memberId);
            if (member == null) {
                continue;
            }
            this.initCopartner(member);
        }
    }

    @Transactional
    public void initCopartner(Member member) {
        member.setIsCopartner(YesNoStatus.YES.getCode());
        member.setType(Member.MEMBER_PERSONAL);
        member.setUpdateDate(null);
        memberService.update(member);

        boolean copartnerFlag = sysRoleService.hasRole(member.getId(), RoleEnum.COPARTNER_ROLE.getCode());
        if (!copartnerFlag) {
            SysRole copartner = getSysRole(RoleEnum.COPARTNER_ROLE.getCode(), RoleType.SYSTEM_ROLE.getCode());
            MemberSysRole memberSysRole = new MemberSysRole(member.getId(), copartner.getId());
            memberSysRoleService.insert(memberSysRole);
        }
    }

    /**
     * 拼接用户状态参数
     *
     * @param memberType 用户类型
     * @param status     状态
     * @param params     参数集合
     */
    public void appendUserStatus(String memberType, String status, Map<String, Object> params) {
        Set<String> statuss = new HashSet<String>();
        if (StringUtils.isNotEmpty(memberType)) {
            String[] str = memberType.split(":");
            if (str[0].equals("userStatus")) {
                if (str[1].equals("2")) {
                    params.put("isReal", true);
                } else {
                    statuss.add(str[1]);
                    params.put(str[0], statuss);
                }
            } else {
                params.put(str[0], str[1]);
            }
        }

        if (StringUtils.isNotEmpty(status)) {
            for (String s : status.split(",")) {
                statuss.add(s);
            }
            params.put("userStatus", statuss);
        }
    }

    /**
     * @Description: 替换手机号
     * @Param:
     * @return:
     * @Author: Hua Qunhao
     * @Date: 2019/12/13
     */
    public String replacePhone(String memberId, String phone) {
        try {
            //替换手机号
            boolean resutle = sysRoleService.hasRole(memberId, RoleEnum.FINANCE_ROLE.getCode());
            if (resutle) {
                phone = StringUtils.replacePhone(phone);
            }
        } catch (Exception e) {
            logger.error("替换手机号异常");
        }
        return phone;
    }
}
